package com.demo.backtemplate.service.impl;

import com.demo.backtemplate.models.dto.RegisterDTO;
import com.demo.backtemplate.utils.StringUtil;
import com.xlf.utility.BaseResponse;
import com.xlf.utility.ErrorCode;
import com.xlf.utility.ResultUtil;
import com.xlf.utility.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.demo.backtemplate.mappers.UserMapper;
import com.demo.backtemplate.models.converter.UserConverter;
import com.demo.backtemplate.models.dto.LoginDTO;
import com.demo.backtemplate.models.dto.UserDTO;
import com.demo.backtemplate.models.entity.User;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.demo.backtemplate.service.UserService;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import java.time.LocalDateTime;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
    private final UserMapper userMapper;

    @Override
    @Transactional(readOnly = true)
    public ResponseEntity<BaseResponse<UserDTO>> login(LoginDTO loginDTO) {
        try {
            log.info("处理用户登录请求，用户名: {}", loginDTO.getUsername());
            
            // 根据用户名查询用户
            User user = userMapper.findByUsername(loginDTO.getUsername());
            log.info("查询到的用户信息: {}", user);
            
            if (user == null) {
                log.warn("用户不存在: {}", loginDTO.getUsername());
                throw new BusinessException("用户不存在", ErrorCode.NOT_EXIST);
            }

            // 检查用户状态
            if (user.getStatus() != null && user.getStatus() == 0) {
                log.warn("用户已被停用: {}", loginDTO.getUsername());
                throw new BusinessException("用户已被停用", ErrorCode.FORBIDDEN);
            }

            // 验证密码
            log.info("开始验证密码");
            boolean passwordMatch = StringUtil.passwordCheck(loginDTO.getPassword(), user.getPassword());
            log.info("密码验证结果: {}", passwordMatch);
            
            if (!passwordMatch) {
                log.warn("密码验证失败，用户名: {}", loginDTO.getUsername());
                throw new BusinessException("密码错误", ErrorCode.PARAMETER_ERROR);
            }

            log.info("用户登录成功，用户ID: {}", user.getUserId());
            
            // 使用转换器将实体转换为DTO（自动处理脱敏）
            UserDTO userDTO = UserConverter.toDTO(user);
            if (userDTO == null) {
                log.error("用户DTO转换失败，用户ID: {}", user.getUserId());
                throw new BusinessException("用户信息转换失败", ErrorCode.OPERATION_FAILED);
            }

            // 生成token
            String token = StringUtil.generateToken(user.getUserId(), user.getUsername());
            userDTO.setToken(token);

            // 将用户信息存入session
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            HttpSession session = request.getSession();
            session.setAttribute("user", user);
            log.info("用户信息已存入session");

            // 返回用户信息
            return ResultUtil.success("登录成功", userDTO);
        } catch (Exception e) {
            log.error("登录过程中发生错误", e);
            throw e;
        }
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseEntity<BaseResponse<UserDTO>> getUserInfo() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            HttpSession session = request.getSession();
            User user = (User) session.getAttribute("user");
            
            if (user == null) {
                log.warn("用户未登录");
                throw new BusinessException("用户未登录", ErrorCode.UNAUTHORIZED);
            }

            UserDTO userDTO = UserConverter.toDTO(user);
            if (userDTO == null) {
                log.error("用户DTO转换失败，用户ID: {}", user.getUserId());
                throw new BusinessException("用户信息转换失败", ErrorCode.OPERATION_FAILED);
            }

            return ResultUtil.success("获取用户信息成功", userDTO);
        } catch (Exception e) {
            log.error("获取用户信息过程中发生错误", e);
            throw e;
        }
    }

    @Override
    public ResponseEntity<BaseResponse<Void>> logout() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            HttpSession session = request.getSession();
            session.invalidate();
            log.info("用户已登出");
            return ResultUtil.success("登出成功");
        } catch (Exception e) {
            log.error("登出过程中发生错误", e);
            throw e;
        }
    }

    @Override
    public ResponseEntity<BaseResponse<Void>> register(RegisterDTO registerDTO) {
        try {
            log.info("处理用户注册请求，用户名: {}", registerDTO.getUsername());
            
            // 检查用户名是否已存在
            if (userMapper.findByUsername(registerDTO.getUsername()) != null) {
                log.warn("用户名已存在: {}", registerDTO.getUsername());
                throw new BusinessException("用户名已存在", ErrorCode.PARAMETER_ERROR);
            }

            // 验证密码和确认密码是否一致
            if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
                log.warn("密码和确认密码不一致");
                throw new BusinessException("密码和确认密码不一致", ErrorCode.PARAMETER_ERROR);
            }

            // 密码加密
            String encryptedPassword = StringUtil.passwordEncryption(registerDTO.getPassword());
            
            // 创建用户实体
            User user = new User();
            user.setUsername(registerDTO.getUsername());
            user.setPassword(encryptedPassword);
            user.setStatus(1); // 设置用户状态为启用
            user.setCreateTime(LocalDateTime.now());
            user.setRealName(registerDTO.getRealName());
            user.setPhone(registerDTO.getPhone());
            
            // 保存用户信息
            int result = userMapper.insert(user);
            if (result <= 0) {
                log.error("用户注册失败，用户名: {}", registerDTO.getUsername());
                throw new BusinessException("注册失败", ErrorCode.OPERATION_FAILED);
            }
            
            log.info("用户注册成功，用户ID: {}", user.getUserId());
            return ResultUtil.success("注册成功");
        } catch (Exception e) {
            log.error("注册过程中发生错误", e);
            throw e;
        }
    }
}